Amazon CloudFrontのContinuous DeploymentでHeader-basedな振り分けをしてみた

Amazon CloudFrontのContinuous DeploymentでHeader-basedな振り分けをしてみた

CloudFrontのContinuous Deploymentでは全リクエストの0-15%をStagingに振り分けるWeight-basedのほか、Header-basedでの振り分けについても対応しています。実際に動作を確認してみました。
Clock Icon2022.11.22

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

清水です。先日リリースされたAmazon CloudFrontのContinuous Deployment(継続的デプロイ)機能、速報ブログではAWS Blogの内容にならいWeight-basedなトラフィックの振り分けで機能を確認してみました。

Staging Distributionへのリクエストの振り分けは、この割合を0%から15%の間で任意に指定できるWeight-basedのほか、指定したヘッダを有する場合にStaging Distributionへリクエストを振り分けるHeader-basedもサポートしています。本エントリでは、このHeader-basedでStaging Distributionにリクエストを振り分けるContinuous Deploymentについて確認してみたのでまとめてみたいと思います。

2023/01/31の時点で、Continuous DeploymentでHeader-basedな振り分けを行う際のヘッダには「aws-cf-cd-」のPrefixを付与することが必須となっていることが確認できました。詳細については以下ブログエントリを参照ください。

CloudFrontのContinuous DeploymentでHeader-basedな振り分けをするときは「aws-cf-cd-」ではじまるヘッダを使おう | DevelopersIO

CloudFrontのContinuous DeploymentでHeader-basedでのStaging環境への振り分け

動作検証のシナリオとオリジンサーバ準備

先日のWeight-basedでの動作検証の際と、基本的には同様の動作検証シナリオ、オリジンサーバ環境とします。

オリジンサーバには以下2つのパスを準備しました。(実際は先日のWeight-basedでの動作検証のときに使用したversion1のパスも存在しています。)

  • http://origin.example.com/version2/
    • テキストver.2を返す
  • http://origin.example.com/version3/
    • テキストver.3を返す

CloudFrontでPrimary Distributionの設定として、Origin path設定で/version2を指定しておきます。(先日のWeight-basedでの動作検証でStaging DistributionをPromoteした状態です。)CloudFrontに設定した独自ドメイン(のインデックスルートドキュメント)にアクセスするとテキストver.2が返る状態となります。

  • 変更前のDistribution設定
    • https://www.example.com/
      • テキストver.2を返す

Staging Distributionの設定では、Origin path設定で/version3を指定します。この状態で、Staging Distributionに割り振られるリクエストについては、CloudFrontに設定した独自ドメイン(のインデックスルートドキュメント)にアクセスするとテキストver.3が返る状態となります。Weight-basedであれば一定量(指定の割合)のリクエストがStaging Distributionに割り振られますが、Header-basedではリクエスト時にHeaderを指定します、このHeaderがあるリクエストについてはStaging Distributionに割り振られるぐあいですね。

  • 変更前のDistribution設定
    • https://www.example.com/ (指定のHeaderを指定)
      • テキストver.3を返す

指定のHeaderを付与した環境で動作確認を経たあと、Staging DistributionをPromote(昇格)させます。これにより、独自ドメイン全体で変更後のDistribution設定となり、アクセスするとテキストver.3が返るようになります。

  • Promote後のDistribution設定
    • https://www.example.com/
      • テキストver.3を返す

Continuous deployment policyとStaging Distributionの変更

オリジンサーバと同じく、CloudFront環境についても先日のWeight-basedでの動作検証のものを使用しました。(Route 53による独自ドメイン設定も実施済みです。)このときはStaging DistributionをWeight-basedのPolicyで作成、動作確認したStaging Distributionの設定をPromote(昇格)させています。

さてこのStaging DistributionをPrimary DistributionにPromoteしたあとですが、以下のようにContinuous Deployment Policyが無効(Disable、つまりEnableにチェックがついていない状態)となっています。Promote後はすべてのトラフィックがPrimary Distributionに振り分けられている、ということになりますね。(この動作はDeveloper Guideにも記載があります。)

さて、まずはこのContinuous Deployment PolicyのTypeをWeight-basedからHeader-basedに変更します。HeaderならびにValueの欄が現れますので、任意のものを入力します。今回は以下のように指定しました。(実際は推測が難しい、複雑な文字列などとすると良いかと思います。)Staging Distributionへのリクエストの割り振りを有効にするEnableのチェックを有効にして[Save changes]でContinuous Deployment Policyの設定を反映させます。(リクエスト割り振り有効化については、Staging Distributionの設定を変更後にEnabledとするほうが良いケースが多いかと思います。実際の運用にあわせましょう。)

  • Header
    • x-cf-cd
  • Value
    • true

2023/01/31の時点で、Continuous DeploymentでHeader-basedな振り分けを行う際のヘッダには「aws-cf-cd-」のPrefixを付与することが必須となっていることが確認できました。詳細については以下ブログエントリを参照ください。

CloudFrontのContinuous DeploymentでHeader-basedな振り分けをするときは「aws-cf-cd-」ではじまるヘッダを使おう | DevelopersIO

Continuous Deployment Policyが設定できました。

続いてStaging Distributionの設定変更を行います。Primary Distributionの画面からContinuous deploymentの項目、Staging distribution IDをクリックしてStaging Distributionの設定画面に進みましょう。

Staging Distributionの画面ですが、従来のDistribution設定画面と項目としては同じかと思います。Origin Path設定を変更したいので、「Origins」タブに進み該当のオリジンを選択して[Edit]します。

[Save changes]すると、Staging Distribution自体がDeploying状態になります。Deploy後のLast modifiedに日付が表示される状態になるまでしばし待ちましょう。(きちんと計測していませんが、体感的には通常の(Primary)DistributionのDeployと同じぐらいの時間がかかる感じです。)

Staging Distributionの設定変更が完了しました!

Staging Distributionに対して動作確認

Staging Distributionへの新しい設定(Origin Pathを/version3とする)の投入が完了しました。続いて、このStaging Distributionに対して動作確認を行います。先日のWeight-basedでの動作検証では、例えば割合を10%としていれば、10回のリクエストのうち1回はStaging Distributionへリクエストが割り振られていたわけですが、Header-basedとした場合には通常のリクエストではStaging Distributionへはリクエストは割り振られません。

% for i in {1..10}; do curl https://cloudfront-continuous-deployment.example.net/; done
ver.2
ver.2
ver.2
ver.2
ver.2
ver.2
ver.2
ver.2
ver.2
ver.2

リクエスト時に指定のヘッダを指定する必要があります。curlコマンドに-Hオプションでヘッダを指定してリクエストしてみます。ver.3の文字列が返ってきましたね!

% curl -H "x-cf-cd: true" https://cloudfront-continuous-deployment.example.net/
ver.3

当然ですが、Headerで異なったValueを指定していた場合はPrimary Distributionにリクエストが割り振られます。

% curl -H "x-cf-cd: false" https://cloudfront-continuous-deployment.example.net/
ver.2

Webブラウザで動作確認を行う場合は、ブラウザの拡張ツールでリクエスト時のHeaderを追加するのが手っ取り早いかと思います。ただし、その拡張ツールが安全なものであるか、しっかりと確認して使用しましょう。(拡張ツールについては、アップデートなどで突然不正行為をはたらくようになるというケースもあるかと思います。)今回はGoogle ChromeでModHeader - Modify HTTP headersという拡張機能を使用してみました。(ただしこの拡張機能が明確に安全である、という保証はありません。ご利用の場合は自己責任でお願いします。)

Headerを追加しない場合は、ver.2が返りました。

でRequest headersを追加して、リロードしてみます。

Staging Distributionにリクエストが振り分けられ、ver.3が返ってきました。

Chromeのデベロッパーツールを確認すると、リクエスト時に指定したHeaderが付与されていることが確認できます。

Staging DistributionをPromote(昇格)

リクエスト時に指定のHeaderを追加した環境での動作確認を終えたら、このStaging DistributionをPromoteしてPrimary Distributionに設定をコピーします。この手順はWeight-basedの場合と特に変わりありませんね。

今回はPrimary Distributionの詳細画面の[Promote]ボタンで実施してみます。

注意事項が表示されますので、確認ののちconfirmをテキストボックスにタイプ、[Promote]ボタンを押下します。(なお、Staging DistributionのDescription内容自体についてはPrimary Distributionにコピーされないことがわかったため、先ほどから内容を変更しています。)

いざ昇格!

画面上部に「Successfully updated distribution E2HSXXXXXXXXXX settings」 のメッセージが表示されます。

また一覧画面から再度Primary Distributionの詳細画面に遷移してみると、Last modifiedの欄がDeployingとDeploy中となっていることがわかります。

しばらくするとDeployが完了します。Continuous Deployment Policyについても、Staging Distributionへの振り分けが無効(Disabled)となっていますね。

ヘッダなしのリクエストでも、変更後の設定内容であるver.3が返るようになっていることが確認できます。

% curl https://cloudfront-continuous-deployment.example.net/
ver.3

まとめ

Amazon CloudFrontのContinuous DeploymentでHeader-basedのトラフィック振り分けを確認してみました。実際に不特定多数のユーザの一部だけをStaging Distributionに振り分ける場合はWeight-basedを利用、その前段階でテストユーザのみStaging Distributionに振り分けたい場合はHeader-basedを使う、というぐあいに適宜目的に応じて使い分けていきましょう。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.